package core.smartCardReader;

import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

import javax.smartcardio.Card;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.TerminalFactory;

import jnasmartcardio.Smartcardio;

import org.springframework.stereotype.Service;

@SuppressWarnings("restriction")
@Service
public class SmartCardReaderService {

	private TerminalFactory terminalFactory;

	private Boolean isInDebugMode;
	private static final String DEBUG_ADMIN_TOKEN_STRING = "53b28aa1-47c8-428e-989b-76b7658008fa";
	private static final String DEBUG_VOTING_TOKEN_STRING = "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF";

	public SmartCardReaderService() {
		try {
			Security.addProvider(new Smartcardio());
			terminalFactory = TerminalFactory.getInstance("PC/SC", null, Smartcardio.PROVIDER_NAME);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchProviderException e) {
			e.printStackTrace();
		}
	}

	public void setIsInDebugMode(Boolean isInDebugState) {
		this.isInDebugMode = isInDebugState;
	}

	public List<TokenCard> getInsertedTokenCards() throws CardException {
		if (isInDebugMode) {
			return Collections.emptyList();
		}
		List<TokenCard> instertedTokenCards = new ArrayList<TokenCard>();
		for (CardTerminal cardTerminal : terminalFactory.terminals().list()) {
			if (cardTerminal.isCardPresent()) {
				Card card = cardTerminal.connect("*");
				instertedTokenCards.add(new TokenCard(card));
			}
		}
		return instertedTokenCards;
	}

	public UUID getFirstAdminToken() throws CardException {
		if (isInDebugMode) {
			return UUID.fromString(DEBUG_ADMIN_TOKEN_STRING);
		}
		for (TokenCard tokenCard : getInsertedTokenCards()) {
			if (tokenCard.isAdminToken()) {
				return tokenCard.readAdminToken();
			}
		}
		return null;
	}

	public UUID getFirstVotingToken() throws CardException {
		if (isInDebugMode) {
			return UUID.fromString(DEBUG_VOTING_TOKEN_STRING);
		}
		for (TokenCard tokenCard : getInsertedTokenCards()) {
			if (tokenCard.isVotingToken()) {
				return tokenCard.readVotingToken();
			}
		}
		return null;
	}

	public static void main(String[] args) throws CardException {
		SmartCardReaderService smartCardReaderService = new SmartCardReaderService();
		smartCardReaderService.setIsInDebugMode(false);
//		smartCardReaderService.getInsertedTokenCards().get(0).writeAdminToken(UUID.fromString("6ab9334d-39f1-4844-8e40-83d8a6135eb3"));
		for(TokenCard tokenCard : smartCardReaderService.getInsertedTokenCards()) {
			System.out.println(tokenCard.readAdminToken().toString());
			System.out.println(tokenCard.readVotingToken());
		}
	}
}
